#include "infiniteAlgorithm.h"
#include "debug.h"
#include "charger.h"
#include "env.h"
#include "uiService.h"
#include "u8g2PageMain.h"
#include "mahCaclService.h"
#define OUTPUT_VOLT 13.8
#define WAIT_4MOS_STABLE_TIME_MS 2000
#define WAIT_4MOS_STABLE_TIME_CNT (WAIT_4MOS_STABLE_TIME_MS / INFINITE_ALGORITHM_DURATION)
extern U8g2PageMainParms disp;

typedef enum
{
    E_IA_DECIDE_POWER,
    E_IA_WAIT_4MOS_STABLE,
    E_IA_OUTPUT_CHECK,
    E_IA_CHARGING,
    E_IA_FINISH,
} IAEnum;
static IAEnum stat = E_IA_DECIDE_POWER;
static float caclFloatCurrent = 0.0;
static unsigned int waitForStableCnt = 0;
void infiniteAlgorithmLoop(void)
{
    if (env.ready == E_SUPPLY_NOT_READY || env.error == E_CRITICAL)
    {
        chargerOutputDisable();
        return;
    }

    disp.batteryCurrent = getOutputCurrent();
    disp.batteryVoltage = getOutputVoltage();
    disp.batteryTemperature = coreTemperature();

    switch (stat)
    {
    case E_IA_DECIDE_POWER:
        // 判断充电器输入条件，并设置对应的输出电流，避免出线过载过温
        if (env.chargerMode == E_CHARGE_MODE_PD)
        {
            float maxPower = env.sourceCapCurrent * env.sourceCapVoltage;
            caclFloatCurrent = maxPower / OUTPUT_VOLT;
        }
        else if (env.chargerMode == E_CHARGE_MODE_QC || env.chargerMode == E_CHARGE_MODE_NONE)
        {
            setChargerMaxCurrent(MAX_CURRENT_DEF);
            if (env.sourceCapVoltage < 1.0)
            {
                setMTTPTrackerVolt(MTTP_DISABLE);
            }
            if (env.sourceCapVoltage < 5.5)
            {
                setMTTPTrackerVolt(MTTP_5V);
            }
            else if (env.sourceCapVoltage < 9.5)
            {
                setMTTPTrackerVolt(MTTP_9V);
            }
            else if (env.sourceCapVoltage < 12.5)
            {
                setMTTPTrackerVolt(MTTP_12V);
            }
            else
            {
                setMTTPTrackerVolt(MTTP_DISABLE);
            }
            caclFloatCurrent = MAX_CURRENT_DEF;
        }
        chargerEnable(); // 需等待2S
        stat = E_IA_WAIT_4MOS_STABLE;
        break;
    case E_IA_WAIT_4MOS_STABLE:
        if (waitForStableCnt >= WAIT_4MOS_STABLE_TIME_CNT)
        {
            waitForStableCnt = 0;
            smAHReset();
            disp.totalChargedmAH = mAH;
            stat = E_IA_OUTPUT_CHECK;
        }
        else
        {
            waitForStableCnt++;
        }

        break;
    case E_IA_OUTPUT_CHECK:
        if (disp.batteryVoltage < 1.0)
        {
            disp.chargeStatus = E_U8G2_CHARGE_STATUS_NOT_IN_CHARGE;
            chargerOutputDisable();
        }
        else if (isChargingFinished())
        {
            stat = E_IA_FINISH;
        }
        else
        {
            stat = E_IA_CHARGING;
        }
        break;
    case E_IA_CHARGING:
        disp.totalChargedmAH = mAH;
        if (disp.batteryTemperature > 70.00)
        {
            disp.chargeStatus = E_U8G2_CHARGE_STATUS_HEAT;
            chargerOutputDisable();
        }
        if (disp.batteryTemperature >= 60.00)
        {
            disp.chargeStatus = E_U8G2_CHARGE_STATUS_INCHARGE;
            setChargerMaxCurrent(caclFloatCurrent / 4);
            chargerOutputEnable();
        }
        else if (disp.batteryTemperature > 50.00)
        {
            disp.chargeStatus = E_U8G2_CHARGE_STATUS_INCHARGE;
            setChargerMaxCurrent(caclFloatCurrent / 2);
            chargerOutputEnable();
        }
        else
        {
            disp.chargeStatus = E_U8G2_CHARGE_STATUS_INCHARGE;
            setChargerMaxCurrent(caclFloatCurrent);
            chargerOutputEnable();
        }

        if (isChargingFinished())
        {
            stat = E_IA_FINISH;
        }

        if (disp.batteryVoltage < 1.0 || disp.batteryCurrent <= 0.02)
        {
            stat = E_IA_OUTPUT_CHECK;
        }

        break;
    case E_IA_FINISH:
        if (disp.batteryVoltage < 1.0)
        {
            chargerOutputDisable();
            stat = E_IA_OUTPUT_CHECK;
        }
        disp.chargeStatus = E_U8G2_CHARGE_STATUS_FULL;
        break;
    }
}
